package com.xbongbong.paas.service.imp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.service.WebHookService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DigestUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.uitl.AsyncHttpClientUtil;
import com.xbongbong.pro.api.pojo.ApiWebHookRabbitMqDTO;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerCommunicateModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.QuotationModel;
import com.xbongbong.saas.model.SupplierModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.saas.model.WorkOrderModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * webHook
 */
@Service("webHookService")
public class WebHookServiceImpl implements WebHookService {
    private static final Logger LOG = LoggerFactory.getLogger(WebHookServiceImpl.class);

    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private ClueModel clueModel;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private CustomerCommunicateModel customerCommunicateModel;
    @Resource
    private QuotationModel quotationModel;
    @Resource
    private SupplierModel supplierModel;
    @Resource
    private WorkOrderModel workOrderModel;


    @Override
    public void send(ApiWebHookRabbitMqDTO apiWebHookRabbitMqDTO) throws XbbException {
        String corpid = apiWebHookRabbitMqDTO.getCorpid();
        Integer saasMark = apiWebHookRabbitMqDTO.getSaasMark();
        List<Long> dataIdList = apiWebHookRabbitMqDTO.getDataIdList();
        XbbRefTypeEnum xbbRefTypeEnum = apiWebHookRabbitMqDTO.getXbbRefType();
        OperateTypeEnum operate = apiWebHookRabbitMqDTO.getOperate();
        String url = apiWebHookRabbitMqDTO.getUrl();
        String token = apiWebHookRabbitMqDTO.getToken();
        Integer isRetry = apiWebHookRabbitMqDTO.getIsRetry();
        LOG.info("webHook apiWebHookRabbitMqDTO:" + apiWebHookRabbitMqDTO);
        if (Objects.isNull(operate) || StringUtil.isEmpty(url) || CollectionsUtil.isEmpty(dataIdList)) {
            return;
        }
        List<PaasFormDataEntity> paasFormDataEntityExtList = getPaasFormDataEntitys(xbbRefTypeEnum, corpid, dataIdList);
        if (CollectionsUtil.isNotEmpty(paasFormDataEntityExtList)) {
            for (PaasFormDataEntity paasFormData : paasFormDataEntityExtList) {
                try {
                    Long formId = paasFormData.getFormId();
                    Long dataId = paasFormData.getDataId();
                    callbackPost(corpid, saasMark, formId, dataId, operate, url, xbbRefTypeEnum, token, isRetry);
                } catch (Exception e) {
                    LOG.error("callbackRetryPost error", e);
                }
            }
        }
    }

    public static void callbackPost(String corpid, Integer saasMark, Long formId, Long dataId, OperateTypeEnum operate, String url, XbbRefTypeEnum xbbRefTypeEnum, String token, Integer isRetry) {
        JSONObject body = new JSONObject();
        body.put("corpid", corpid);
        body.put("saasMark", saasMark);
        body.put("formId", formId);
        body.put("dataId", dataId);
        body.put("operate", operate.getAlias());
        if (!Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.SYSTEM)) {
            body.put("type", xbbRefTypeEnum.getAlias());
        }
        String sign = null;
        if (!StringUtil.isEmpty(token)) {
            sign = DigestUtil.Encrypt(body.toJSONString() + token, "SHA-256");
        }
        if (Objects.equals(isRetry, 1)) {
            AsyncHttpClientUtil.executeRetryPost(url, JSON.toJSONString(body), token, sign);
        } else {
            AsyncHttpClientUtil.executePost(url, JSON.toJSONString(body), token, sign);
        }
    }

    /**
     * 获取表单数据
     * @param xbbRefTypeEnum 业务类型
     * @param corpid 公司id
     * @param dataIdList
     * @return 表单数据实体
     */
    private List<PaasFormDataEntity> getPaasFormDataEntitys(XbbRefTypeEnum xbbRefTypeEnum, String corpid, List<Long> dataIdList) {
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.ID_IN, dataIdList);
        param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
        param.put(ParameterConstant.COLUMNS, "id, corpid, form_id");
        List paasFormDataEntityExts = null;
        switch (xbbRefTypeEnum) {
            case SYSTEM:
                paasFormDataEntityExts =  paasFormDataModel.findEntitysWithoutSub(param);
                break;
            case CUSTOMER:
            case CUSTOMER_MANAGEMENT:
                paasFormDataEntityExts = customerModel.findEntitysWithoutSub(param);
                break;
            case CONTRACT:
                paasFormDataEntityExts = contractModel.findEntitysWithoutSub(param);
                break;
            case CONTACT:
                paasFormDataEntityExts = contactModel.findEntitysWithoutSub(param);
                break;
            case SALES_OPPORTUNITY:
                paasFormDataEntityExts = opportunityModel.findEntitysWithoutSub(param);
                break;
            case PAYMENT:
                paasFormDataEntityExts = paymentModel.findEntitysWithoutSub(param);
                break;
            case PAYMENT_SHEET:
                //只回调只有父无子和父的回款单
                param.put("aloneIn", SheetAloneEnum.getNotChildCodeList());
                paasFormDataEntityExts = paymentSheetModel.findEntitysWithoutSub(param);
                break;
            case PRODUCT:
                //只回调父产品
                param.put("dataParentId", 0);
                paasFormDataEntityExts = productModel.findEntitysWithoutSub(param);
                break;
            case CLUE:
                paasFormDataEntityExts = clueModel.findEntitysWithoutSub(param);
                break;
            case PURCHASE:
                paasFormDataEntityExts = purchaseModel.findEntitysWithoutSub(param);
                break;
            case WAREHOUSE:
                paasFormDataEntityExts = warehouseModel.findEntitysWithoutSub(param);
                break;
            case CUSTOMER_COMMUNICATE:
                param.remove(ParameterConstant.FLOW_STATUS_IN);
                paasFormDataEntityExts = customerCommunicateModel.findNotAutGenEntitysWithoutSub(param);
                break;
            case QUOTATION:
                paasFormDataEntityExts = quotationModel.findEntitysWithoutSub(param);
                break;
            case PRODUCT_CATEGORY:
                paasFormDataEntityExts = new ArrayList(dataIdList.size());
                for (Long dataId : dataIdList) {
                    PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
                    paasFormDataEntity.setCorpid(corpid);
                    paasFormDataEntity.setDataId(dataId);
                    paasFormDataEntity.setId(dataId);
                    paasFormDataEntity.setFormId(0L);
                    paasFormDataEntityExts.add(paasFormDataEntity);
                }
                break;
            case SUPPLIER:
                paasFormDataEntityExts = supplierModel.findEntitysWithoutSub(param);
                break;
            case WORK_ORDER:
                paasFormDataEntityExts = workOrderModel.findEntitysWithoutSub(param);
                break;
            default:
                return null;
        }
        if (CollectionsUtil.isNotEmpty(paasFormDataEntityExts)) {
            return (List<PaasFormDataEntity>)paasFormDataEntityExts;
        }
        return null;
    }
}
